#ifndef MQTT_MANAGER_H
#define MQTT_MANAGER_H

#include <WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "pattern_loader.h"
#include "motion_controller.h"
#include "led_manager.h"

// 前向声明
class CommandExecutor;

class MQTTManager {
private:
  // ===========================================
  // 配置常量
  // ===========================================
  static const char* MQTT_SERVER;
  static const int MQTT_PORT = 8883;
  static const char* MQTT_USERNAME;
  static const char* MQTT_PASSWORD;
  static const unsigned long RECONNECT_INTERVAL = 5000;
  static const unsigned long HEARTBEAT_INTERVAL = 30000;
  static const int MAX_CONNECTION_RETRIES = 5;
  static const unsigned long MAX_RECONNECT_INTERVAL = 300000; // 5分钟最大重连间隔
  static constexpr float BACKOFF_MULTIPLIER = 1.5f; // 指数退避倍数
  static const int MQTT_BUFFER_SIZE = 1024;
  static const int JSON_BUFFER_SIZE = 512;
  static const int HEARTBEAT_JSON_SIZE = 1200; // 增加以支持复杂的心跳格式(pattern+playback+lightSettings)
  static const int CONNECTION_TIMEOUT = 15;
  static const int KEEPALIVE_INTERVAL = 60;
  static const unsigned long STATUS_LOG_INTERVAL = 120000;  // 2分钟
  static const unsigned long HEARTBEAT_LOG_INTERVAL = 300000; // 5分钟
  
  // 日志级别
  enum LogLevel {
    LOG_ERROR = 0,
    LOG_WARN = 1,
    LOG_INFO = 2,
    LOG_DEBUG = 3
  };
  
  static const LogLevel DEFAULT_LOG_LEVEL = LOG_INFO;
  
  // ===========================================
  // 核心组件
  // ===========================================
  CommandExecutor* commandExecutor;
  PatternLoader* patternLoader;
  WiFiClientSecure* mqttWiFiClient;
  PubSubClient* mqttClient;
  
  // ===========================================
  // 连接状态管理
  // ===========================================
  bool mqttConnected;
  unsigned long lastReconnectAttempt;
  int connectionRetries;
  unsigned long connectionStartTime;
  
  // 指数退避重连参数
  unsigned long baseReconnectInterval;
  unsigned long maxReconnectInterval;
  float backoffMultiplier;
  
  // 连接稳定性监控
  unsigned long lastSuccessfulConnection;
  int consecutiveFailures;
  
  // ===========================================
  // 性能监控统计
  // ===========================================
  unsigned long totalConnectionAttempts;
  unsigned long successfulConnections;
  unsigned long totalMessagesSent;
  unsigned long totalMessagesReceived;
  unsigned long totalMessagesFailed;
  unsigned long totalBytesTransmitted;
  unsigned long connectionTotalTime;
  
  // ===========================================
  // 心跳和监控
  // ===========================================
  unsigned long lastHeartbeat;
  unsigned long lastStatusLog;
  unsigned long lastHeartbeatLog;
  
  // ===========================================
  // 日志管理
  // ===========================================
  LogLevel currentLogLevel;
  
  // ===========================================
  // 设备状态
  // ===========================================
  String deviceSN;
  bool isDrawing;
  bool isPaused;
  int currentPatternIndex;
  
  // 播放列表状态
  DynamicJsonDocument* currentPlaylist;
  static const String PLAYLIST_FILE_PATH;
  
  // ===========================================
  // 连接管理
  // ===========================================
  bool connectWithHostname();
  bool initializeSSLConnection();
  void printMQTTError(int errorCode);
  
  // 高级连接管理
  unsigned long getNextReconnectInterval();
  void resetConnectionRetries();
  bool shouldAttemptReconnect();
  void handleConnectionFailure();
  
  // ===========================================
  // 消息处理
  // ===========================================
  void mqttCallback(char* topic, byte* payload, unsigned int length);
  void subscribeToTopics();
  void handleCommand(const String& command, const DynamicJsonDocument& payload);
  bool parseJsonMessage(const String& message, DynamicJsonDocument& doc);
  
  // 模板方法实现（必须在头文件中）
  template<size_t N>
  bool parseStaticJson(const String& message, StaticJsonDocument<N>& doc) {
    DeserializationError error = deserializeJson(doc, message);
    if (error) {
      logError("静态JSON解析失败: " + String(error.c_str()));
      return false;
    }
    return true;
  }
  
  // ===========================================
  // 命令处理
  // ===========================================
  void handleBasicCommands(const String& command, const DynamicJsonDocument& payload);
  void handleMotionCommands(const String& command, const DynamicJsonDocument& payload);
  void handleLEDCommands(const String& command, const DynamicJsonDocument& payload);
  void handleAutoPlayCommands(const String& command, const DynamicJsonDocument& payload);
  void handleAutoResumeCommands(const String& command, const DynamicJsonDocument& payload);
  void handleSystemCommands(const String& command, const DynamicJsonDocument& payload);
  
  // 🔧 新增：播放列表和下载命令处理
  void handlePlaylistCommands(const String& command, const DynamicJsonDocument& payload);
  void handleDownloadCommands(const String& command, const DynamicJsonDocument& payload);
  
  // 播放列表管理辅助方法
  bool processPlaylistAction(const String& action, const DynamicJsonDocument& payload);
  bool validatePlaylistData(const DynamicJsonDocument& data);
  void publishPlaylistResponse(const String& action, const String& status, const String& message = "");
  
  // THR文件下载辅助方法
  bool processTHRDownload(const DynamicJsonDocument& data);
  bool downloadTHRFile(const String& url, const String& patternId, const String& checksum = "");
  bool downloadTHRFileWithName(const String& url, const String& patternId, const String& fileName, const String& checksum = "");
  void publishDownloadProgress(const String& patternId, int progress, const String& status);
  
  // 分片下载辅助方法
  int getFileSize(const String& url);
  bool downloadInChunks(const String& url, File& file, int fileSize, const String& patternId, 
                       size_t chunkSize, int chunksPerProgressUpdate);
  
  // SD卡播放列表管理方法
  bool loadPlaylistFromSD();
  bool loadPlaylistFromSD(DynamicJsonDocument& playlistData);
  bool savePlaylistToSD(const DynamicJsonDocument& playlistData);
  bool updatePlaylistOnSD(const String& action, const DynamicJsonDocument& payload);
  String getPlaylistFilePath() const;
  bool viewPlaylistFile(); // 查看播放列表文件内容
  
  // ===========================================
  // 消息发布
  // ===========================================
  void publishError(const String& error);
  void publishHeartbeatWithStatus();
  bool publishMessageWithRetry(const String& category, const String& message, int maxRetries = 3);
  
  // ===========================================
  // 工具方法
  // ===========================================
  String buildTopicPath(const String& category);
  String getDeviceSN();
  bool checkMemoryAvailability();
  void logConnectionStatus();
  
  // ===========================================
  // 日志方法
  // ===========================================
  void log(LogLevel level, const String& message);
  void logError(const String& message);
  void logWarn(const String& message);
  void logInfo(const String& message);
  void logDebug(const String& message);
  const char* getLogLevelString(LogLevel level);
  
public:
  // ===========================================
  // 构造与析构
  // ===========================================
  MQTTManager(PatternLoader* loader, MotionController* motion, MotionController* motionForHoming, LEDManager* led);
  ~MQTTManager();
  
  // ===========================================
  // 初始化与配置
  // ===========================================
  void begin();
  void setCommandExecutor(CommandExecutor* executor);
  
  // ===========================================
  // 连接管理
  // ===========================================
  bool connect();
  void disconnect();
  bool isConnected();
  void loop();
  
  // ===========================================
  // 消息发布接口
  // ===========================================
  void publishMessage(const String& category, const String& message);
  void publishStatus(const String& status, const String& message = "");
  void publishDeviceOnline();
  void publishDeviceOffline();
  
  // ===========================================
  // 状态管理
  // ===========================================
  void setDrawingState(bool drawing, bool paused = false);
  void setCurrentPatternIndex(int index);
  
  // 播放列表访问方法
  const DynamicJsonDocument* getCurrentPlaylist() const;
  String getPlaylistSummary() const;
  
  // ===========================================
  // 诊断与调试
  // ===========================================
  void printStatus();
  void printStatistics();
  void printPerformanceStats();
  void resetStatistics();
  void setLogLevel(LogLevel level);
  LogLevel getLogLevel() const;
};

#endif // MQTT_MANAGER_H
